/*=================================================
    File:	zcom_uiIMInbox.c

	Module:	ui
	Author:	Mike	

=================================================*/

#include <zcom_uiIMMain.h>
#include <IMManager.h>
#include <ui.h>
#include <string.h>
#include <display.h>
#include <zcom_uiTextDialog.h>

#if 1
#define dbgf	debugf
#endif //1

static int	g_idxInbox = -1;

//for update issue
typedef struct
{
	bool bInboxEnter;
	int	 inboxLevel;
	int  used;
} _INBOX_UPDATE_PARAM;

static _INBOX_UPDATE_PARAM g_iup = {};

//used for scroll text structure...
//set global for all to save memory, but be careful to use
//by Mike
char szMsg_Content[1280];
int  Len_szMsg_Content = sizeof(szMsg_Content);

static void _zcom_uiIMInboxGetNumberCB(char *buf, int bufsize,
        LangIdx idx, int index, void *data)
{
    sprcpy(buf, bufsize, " "); //use blank
	char number[CFG_PHONEBOOK_DIGIT_MAX+1];
	int id = (int) data;
	if(id<0)
		return;

	if (IM_InBox_GetMsgNumberInfoByIndex(id, number, CFG_PHONEBOOK_DIGIT_MAX))
	{
		bool isRead = true;
		IM_InBox_GetMsgReadFlagByIndex(id, &isRead);
		if(!isRead)
		{
			sprcpy(buf, bufsize, "*");;
		}
		sprcpy(buf+1, bufsize-1, number);
	}
}

static void _zcom_uiIMInboxGetNumberCB2(char *buf, int bufsize,
        LangIdx idx, int index, void *data)
{
    sprcpy(buf, bufsize, "");
	char number[CFG_PHONEBOOK_DIGIT_MAX+1];
	int id = (int) data;
	if(id<0)
		return;

	if (IM_InBox_GetMsgNumberInfoByIndex(id, number, CFG_PHONEBOOK_DIGIT_MAX))
	{
		sprcpy(buf, bufsize, number);
	}
}

static void Inbox_OptionReply(void * data)
{
	if(g_idxInbox<0)
		return;

	if(!IMManager_CanSend())
	{
		uiMenuDialogMesgTimed(
            LANG_Menu_IM_Reply,
            langGet(LANG_ZCOM_Test_WLAN_Text_Not_Ready) 
            );
		return;
	}

	char number[CFG_PHONEBOOK_DIGIT_MAX+1] = {};
	if (IM_InBox_GetMsgNumberInfoByIndex(g_idxInbox, number, CFG_PHONEBOOK_DIGIT_MAX))
	{
		//To do: call write api...
		//by Mike
		zcom_uiIMWriteStart(number);	
	}
}

static void _MsgForwardDone(void * data)
{
	char * str = (char *)data;
	if(g_idxInbox<0)
		return;

	if(str && strlen(str))
	{
		//get number
		char number[CFG_PHONEBOOK_DIGIT_MAX+1]={};
		sprcpy(number, CFG_PHONEBOOK_DIGIT_MAX, str);
		
		//pop
		uiMenuPop(1);

		//go back to in-box
		uiMenuPop(1);
		uiMenuPop(1);

		//send now
		IM_INBOX in = {};
		if(IM_InBox_GetMsgByIndex(g_idxInbox, &in))
		{
			dbgf("Forward msg to %s\n", number);
			int err = IMManager_SendOutMsg(number, in.msg);
			if(err>=0)
			{
				uiMenuDialogMesgTimed(
					LANG_Menu_IM_Forward,
					langGet(LANG_Menu_IM_Send_Ok) 
					);
			}
			else
			{
				dbgf("Send error(code: %d)!\n", err);
				uiMenuDialogMesgTimed(
					LANG_Menu_IM_Forward,
					langGet(LANG_Menu_IM_Send_Fail) 
					);
			}
		}
	}
}

static void _MsgForwardSearchReady(void *data, const char *str)
{
	if(!str || strlen(str)==0)
	{
		//pop it...
		uiMenuPop(1);
		uiMenuPop(1);

		//warning
		uiMenuDialogMesgTimed(
            LANG_PhoneBook_title,
            langGet(LANG_ZCOM_Test_WLAN_Text_Not_Ready) 
            );
		return;
	}
	
	char number[CFG_PHONEBOOK_DIGIT_MAX+1] = {};
	sprcpy(number, sizeof(number), str);

	uiMenuPop(1);
	//just send it...
	_MsgForwardDone((void *)number);
	return;
}


static void _MsgForwardSearch(void * data)
{
#if 0 //it seems we need do more work than we expected
	//Use user style to draw by ourselves...
	UIMenuUserInit init;
    memset(&init, 0, sizeof(init));

    init.eventHandler   = _MsgForwardSearchWinEvents;
    init.repaintHandler = _MsgForwardSearchWinRepaint;
	init.userData = data;

    uiMenuSoftKeyNegative(init.softKey, LANG_SoftKey_Back);
	uiMenuSoftKeyPositive(init.softKey, LANG_SoftKey_Done);

	uiMenuUserInit(&init, NULL);
#else

	bool hasSIP = false;
	int mode = 0;
	for(int i=0;i<PhoneBook_GetCount();i++)
	{
		if(PhoneBook_RecordGetMode(i, &mode)==0)
		{
			if(!mode)
			{
				hasSIP = true;
				break;
			}
		}
	}
	
	if(!hasSIP)
	{
		//warning
		uiMenuDialogMesgTimed(
            LANG_PhoneBook_title,
            langGet(LANG_ZCOM_Test_WLAN_Text_Not_Ready) 
            );
		return;	
	}
	else
	{
		//use customized text-list menu here
		//by Mike
		UIMenuText_List_PBook_V2_EntryInit init;
		memset(&init, 0, sizeof(init));
		
		init.title.textIdx   = LANG_PhoneBook_search_name;
		//init.title.textIdx   = LANG_NULL;
		
		init.prompt.textIdx  = LANG_PhoneBook_enter_search_name;
		init.doneCB          = _MsgForwardSearchReady;
		init.pkeyTextEntryIdx = LANG_Menu_IM_Send;
		
		init.str[0]          = '\0';
		init.bufSize          = CFG_PHONEBOOK_DIGIT_MAX;
		init.cursorPos       = 0;
		init.shift           = 1;
		
		uiMenuText_List_PBook_V2_EntryInit(&init);
	}
#endif 
}

static void _MsgForwardPkeyClicked(void *arg, const char *str)
{

	if(str && strlen(str)>0)
	{
		//done
		_MsgForwardDone((void *)str);
		
	}
	else
	{
		//do search
		_MsgForwardSearch(NULL);		
	}

}

static void  _MsgForwardStart(void * arg)
{
	//add your codes here
	UIMenuPKeyTextEntryInit init;
    memset(&init, 0, sizeof(init));

    init.title.textIdx   = LANG_Menu_IM_Forward_To;

    init.pkeyCB          = _MsgForwardPkeyClicked;
	init.pkeyTextNotNilEntryIdx = LANG_Menu_IM_Send;
	init.pkeyTextNilEntryIdx = LANG_Menu_Call_Search_title;

    init.str[0]          = '\0';
    init.bufSize          = CFG_PHONEBOOK_DIGIT_MAX;
    init.cursorPos       = 0;
    init.nodeCBArgEx = arg;

    uiMenuPKeyTextEntryInit(&init);
}

static void Inbox_OptionForward(void * data)
{
	if(g_idxInbox<0)
		return;

	if(!IMManager_CanSend())
	{
		uiMenuDialogMesgTimed(
            LANG_Menu_IM_Forward,
            langGet(LANG_ZCOM_Test_WLAN_Text_Not_Ready) 
            );
		return;
	}

	//resend it to another user...
	//by Mike
	_MsgForwardStart(NULL);
	
}

static void _Inbox_DeleteDone(void * data)
{
	if(g_idxInbox<0)
		return;

	//get current num
	int used = g_iup.used;
	//delete the message
	//by Mike
	IM_InBox_DeleteMsgByIndex(g_idxInbox);

	//return to the inbox page...
	uiMenuPop(1);
	uiMenuPop(1);
	uiMenuPop(1);

	//back again
	uiMenuPop(1);
	if(used>1)
	{
		zcom_uiIMInboxStart(NULL);
	}

	uiMenuDialogMesgTimed(
            LANG_Menu_IM_INBOX_Message,
            langGet(LANG_PhoneBook_deletefinish) 
            );
}

static void Inbox_OptionDelete(void * data)
{
	uiMenuDialogMesgYes(
	    LANG_Menu_IM_INBOX_Message,
	    langGet(LANG_Menu_IM_Delete_Query),
	    _Inbox_DeleteDone, NULL,
	    NULL, NULL, NULL);
}

static void _IMInbox_MessageStart(void * data);

static void Inbox_OptionStart()
{
	UIMenuListInit init;
	static UIMenuNode MenuOptionNodes[4] = {};
    MenuOptionNodes[0].text.textIdx = LANG_Menu_IM_Reply; //reply
    MenuOptionNodes[0].selectCB    = Inbox_OptionReply;
    MenuOptionNodes[0].selectCBarg = NULL;

    MenuOptionNodes[1].text.textIdx = LANG_Menu_IM_Forward; //forward
    MenuOptionNodes[1].selectCB    = Inbox_OptionForward;
    MenuOptionNodes[1].selectCBarg = NULL;

	MenuOptionNodes[2].text.textIdx = LANG_SoftKey_Detail; //detail
    MenuOptionNodes[2].selectCB    = _IMInbox_MessageStart;
    MenuOptionNodes[2].selectCBarg = (void *)g_idxInbox;

	MenuOptionNodes[3].text.textIdx = LANG_PhoneSetup_Profiles_delete; //delete
    MenuOptionNodes[3].selectCB    = Inbox_OptionDelete;
    MenuOptionNodes[3].selectCBarg = NULL;


	memset(&init, 0, sizeof(init));
	init.title.textIdx = LANG_SoftKey_Options;
	init.nodes          = MenuOptionNodes;
	init.nNodes         = 4;

	/*
	* Init menu to active
	*/
	uiMenuListInit(&init);
}

static void Inbox_MessageWinRepaint(
        UIMenu *menu,
        Pw_GC *gc,
        Pw_Coord y0,
        Pw_Coord y1
    )
{
	Pw_Coord  w, h;
	Pw_Window *win = Pw_GCGetWindow(gc);
	Pw_WindowGetSize(win, &w, &h);

	if(g_idxInbox>=0)
	{
		IM_INBOX in = {};
		if(IM_InBox_GetMsgByIndex(g_idxInbox, &in))
		{
			char str[UI_MENU_MAXSTR];
			//send
			Pw_GCSetFont(gc, dispFontGet(DISP_FONT_TYPE_REGULAR));
			spr(str, sizeof(str), "%s:", langGet(LANG_Menu_IM_Sender));
			Pw_DrawStringAnchor(gc, 2, y0, str, Pw_TextAnchor_TopLeft);

			y0 += Pw_GCGetFontHeight(gc)+1;

			Pw_GCSetFont(gc, dispFontGet(DISP_FONT_TYPE_SMALL));
			Pw_DrawStringAnchor(gc, 12, y0, in.number, Pw_TextAnchor_TopLeft);

			y0 += Pw_GCGetFontHeight(gc)+3;

			//time
			Pw_GCSetFont(gc, dispFontGet(DISP_FONT_TYPE_REGULAR));
			spr(str, sizeof(str), "%s:", langGet(LANG_Menu_IM_time));
			Pw_DrawStringAnchor(gc, 2, y0, str, Pw_TextAnchor_TopLeft);

			y0 += Pw_GCGetFontHeight(gc)+1;

			Pw_GCSetFont(gc, dispFontGet(DISP_FONT_TYPE_SMALL));
			sprcpy(str, sizeof(str), in.date);
			Pw_DrawStringAnchor(gc, 12, y0, str, Pw_TextAnchor_TopLeft);

			y0 += Pw_GCGetFontHeight(gc);

			sprcpy(str, sizeof(str), in.time);
			Pw_DrawStringAnchor(gc, 12, y0, str, Pw_TextAnchor_TopLeft);
		}
	}

}

static Pw_Bool Inbox_MessageWinEvents(UIMenu *menu, Pw_Event *ev)
{
	switch (Pw_EventGetType(ev))
	{
	    case Pw_KeyPressEventType: {
	        Pw_KeyEvent* kev = Pw_EventCastToKeyEvent(ev);
	        Pw_uInt keycode = Pw_KeyEventGetKeyCode(kev);

	        switch ( keycode ) {

				case KEYSYM_SOFT_POSITIVE:
					break;

	            case KEYSYM_END:
	                uiMainWinKeyEnd();
	                return TRUE;

	            case KEYSYM_SOFT_NEGATIVE:
	                uiMenuPop(1);
	                return TRUE;

	            default:
	                break;
	        }
	    }
	    default:
	        break;
	}

	return FALSE;

}

static void _IMInbox_MessageStart(void * data) //showed in details, according to KM
{
    //show number, time, etc...
	int id = (int) data;
	if(id<0)
		return;

	//save index
	g_idxInbox = id;

	UIMenuUserInit init;
    memset(&init, 0, sizeof(init));

    init.eventHandler   = Inbox_MessageWinEvents;
    init.repaintHandler = Inbox_MessageWinRepaint;

    uiMenuSoftKeyNegative(init.softKey, LANG_SoftKey_Back);

	uiMenuUserInit(&init, NULL);
}

#if 0
static void Inbox_ContentWinRepaint(
        UIMenu *menu,
        Pw_GC *gc,
        Pw_Coord y0,
        Pw_Coord y1
    )
{
	Pw_Coord  w, h;
	Pw_Window *win = Pw_GCGetWindow(gc);
	Pw_WindowGetSize(win, &w, &h);

	if(g_idxInbox>=0)
	{
		IM_INBOX in = {};
		if(IM_InBox_GetMsgByIndex(g_idxInbox, &in))
		{
			//show it
			//No more than 6 lines for small font
			//but in Chinese version, we just got 4 line, poor...
			uiTextLayout(in.msg, 4/*6*/, gc, DISP_FONT_TYPE_SMALL, 0, y0, y1, 0, w);
		}
	}

}

static Pw_Bool Inbox_ContentWinEvents(UIMenu *menu, Pw_Event *ev)
{
	switch (Pw_EventGetType(ev))
	{
	    case Pw_KeyPressEventType: {
	        Pw_KeyEvent* kev = Pw_EventCastToKeyEvent(ev);
	        Pw_uInt keycode = Pw_KeyEventGetKeyCode(kev);

	        switch ( keycode ) {

				case KEYSYM_SOFT_POSITIVE:
					Inbox_OptionStart();
					break;

	            case KEYSYM_END:
	                uiMainWinKeyEnd();
	                return TRUE;

	            case KEYSYM_SOFT_NEGATIVE:
	                uiMenuPop(1);
	                return TRUE;

	            default:
	                break;
	        }
	    }
	    default:
	        break;
	}

	return FALSE;

}
#endif //0

static void scrollText_selectOption(void * arg)
{
	Inbox_OptionStart();
}

static void scrollText_selectBack(void * arg)
{
	uiMenuPop(1);
	if(g_iup.inboxLevel==2)
	{
		g_iup.inboxLevel = 1; 
	}
}

static void _IMInbox_ContentStart(void * data)
{
    //show msg...
	int id = (int) data;
	if(id<0)
		return;

	//save index
	g_idxInbox = id;

	bool bRead = true;
	if(IM_InBox_GetMsgReadFlagByIndex(g_idxInbox, &bRead))
	{
		if (!bRead)
		{
			IM_InBox_SetMsgReadFlagByIndex(g_idxInbox);
		}
	}

#if 0
    UIMenuUserInit init;
    memset(&init, 0, sizeof(init));

    init.eventHandler   = Inbox_ContentWinEvents;
    init.repaintHandler = Inbox_ContentWinRepaint;

    uiMenuSoftKeyNegative(init.softKey, LANG_SoftKey_Back);
    uiMenuSoftKeyPositive(init.softKey, LANG_SoftKey_Options);

	uiMenuUserInit(&init, NULL);
#else
	//use scroll text ui from TJ
	IM_INBOX in = {};
	if(IM_InBox_GetMsgByIndex(g_idxInbox, &in))
	{

		//set level flag
		g_iup.inboxLevel = 2;

		//save msg to szMsg_Content
		//do not use local variant to pass-init
		sprcpy(szMsg_Content, Len_szMsg_Content, in.msg);
		
		UIMenuText title = {};
		SoftKeyParameter pos = {};
		SoftKeyParameter neg = {};

		title.textIdx = LANG_Menu_IM_INBOX_Message;

		pos.textIdx = LANG_SoftKey_Options; 
		pos.selectCB = scrollText_selectOption;

		neg.textIdx = LANG_SoftKey_Back; 
		neg.selectCB = scrollText_selectBack;
		
		//init
		zcom_uiTextDialogInit(szMsg_Content, strlen(szMsg_Content), &title, &pos, &neg);

	}
#endif

}

static void _zcom_uiIMInboxSelected(void *data)
{
	//add your codes here...
#if 0
	UIMenuListInit init;
	static UIMenuNode MenuIBSelectNodes[3] = {};
    MenuIBSelectNodes[0].text.textIdx = LANG_Menu_IM_INBOX_Message; //message
    MenuIBSelectNodes[0].selectCB    = _IMInbox_MessageStart;
    MenuIBSelectNodes[0].selectCBarg = data;

    MenuIBSelectNodes[1].text.textIdx = LANG_Menu_IM_INBOX_Content; //content
    MenuIBSelectNodes[1].selectCB    = _IMInbox_ContentStart;
    MenuIBSelectNodes[1].selectCBarg = data;
	
	memset(&init, 0, sizeof(init));
	init.title.textCB = _zcom_uiIMInboxGetNumberCB2;
	init.title.textCBarg = data;
	init.nodes          = MenuIBSelectNodes;
	init.nNodes         = 2;

	/*
	* Init menu to active
	*/
	uiMenuListInit(&init);
#else
	//show message directly, according to KM
	_IMInbox_ContentStart(data);
#endif
}

static void _inboxCleanupCB(void * arg)
{
	memset(&g_iup, 0 , sizeof(g_iup));
}

void zcom_uiIMInboxStart(void * arg)
{
	int used=0, total;
	if(IM_InBox_GetSize(&used, &total) && used>0)
	{

		UIMenuListInit init;
		static UIMenuNode menuSelectNodes[50];
		int nNodes = 0;
		memset(menuSelectNodes, 0, sizeof(menuSelectNodes));
		
		//Added for inbox full issue, we only show at most total-1 msgs!!!
		//by Mike
		if(used==total)
			used--;

		for (int index = used-1; index >= 0; index--)
		{
			menuSelectNodes[nNodes].text.textCB = _zcom_uiIMInboxGetNumberCB;
			menuSelectNodes[nNodes].text.textCBarg = (void *)index;
			menuSelectNodes[nNodes].selectCB    = _zcom_uiIMInboxSelected;
			menuSelectNodes[nNodes].selectCBarg = (void *)index;
			nNodes++;
			
			if(nNodes>=50)
				break;
		}
		
		memset(&init, 0, sizeof(init));
		init.title.textIdx  = LANG_Menu_IM_INBOX;
		init.nodes          = menuSelectNodes;
		init.nNodes         = nNodes;

		//for update issue
		//by Mike
		init.cleanupCB = _inboxCleanupCB;	
		/*
		* Init menu to active
		*/
		uiMenuListInit(&init);
		
		//after init, allow update
		g_iup.bInboxEnter = true;
		//do not use uiMenuLevelGet() since it is not accurate in time when pop...
		//set inbox level flag
		g_iup.inboxLevel = 1; 
		g_iup.used = nNodes;

		//for inbox full case, we leave last one as reserved use
		//by Mike
		if(used >= total-1) //==total
		{
			char str[32] = {};
			spr(str, sizeof(str), langGet(LANG_Menu_IM_Full_Format), langGet(LANG_Menu_IM_INBOX));
			uiMenuDialogMesgTimed(
					LANG_Menu_IM_INBOX,
					str 
					);
		}
	}
	else
	{
		char str[32];
		spr(str, sizeof(str), langGet(LANG_Menu_IM_Empty_Format), langGet(LANG_Menu_IM_INBOX));
		uiMenuDialogMesgTimed(
				LANG_Menu_IM_INBOX,
				str
				);
	}
}


bool zcom_uiIMInboxGetUnreadMail()
{
	int used=0, total;
	if(IM_InBox_GetSize(&used, &total) && used>0)
	{
		bool bRead = true;
		for(int i=0;i<used;i++)
		{
			if(IM_InBox_GetMsgReadFlagByIndex(i, &bRead) && !bRead)
			{
				return true;
			}
		}
	}

	return false;
}

//add for list update when new message comes
void	zcom_uiIMInbox_Update(int used)
{
	static bool bUpdating = false;
	if(bUpdating)
	{
		return;
	}
	//set flag, just in case
	bUpdating = true;
	
	dbgf("Current level is %d\n", g_iup.inboxLevel);
	//check here
	if(g_iup.bInboxEnter && used > g_iup.used)
	{
		if(g_iup.inboxLevel>0
			&& g_iup.inboxLevel == 1)	 
		{
			//ok, can update
			uiMenuPop(1);
			
			//enter again
			zcom_uiIMInboxStart(NULL);
		}
	}
	
	//reset flag
	bUpdating = false;
}
